package dfl.bysj.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import dfl.bysj.config.RedisKey;
import dfl.bysj.config.model.VO.UserDto;
import dfl.bysj.entity.*;
import dfl.bysj.entity.VO.StudentVO;
import dfl.bysj.exception.Assert;
import dfl.bysj.mapper.*;
import dfl.bysj.result.ResponseEnum;
import dfl.bysj.service.AcademyService;
import dfl.bysj.service.GradeService;
import dfl.bysj.service.StudentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import dfl.bysj.service.UserService;
import dfl.bysj.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author DFL
 * @since 2022-04-26
 */
@Service
@Slf4j
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    private StudentMapper studentMapper;

    private AcademyMapper academyMapper;

    private GradeMapper gradeMapper;

    private UserTeacherStudentMapper userTeacherStudentMapper;

    private RedisTemplate redisTemplate;

    private AcademyService academyService;

    private GradeService gradeService;

    private List<Student> students;

    private AtomicReference<Student> studentAtomicReference= new AtomicReference<>(new Student());



    @Autowired
    public void setGradeService(GradeService gradeService) {
        this.gradeService = gradeService;
    }

    @Autowired
    public void setAcademyService(AcademyService academyService) {
        this.academyService = academyService;
    }


    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Autowired
    public void setUserTeacherStudentMapper(UserTeacherStudentMapper userTeacherStudentMapper) {
        this.userTeacherStudentMapper = userTeacherStudentMapper;
    }

    @Autowired
    public void setGradeMapper(GradeMapper gradeMapper) {
        this.gradeMapper = gradeMapper;
    }

    @Autowired
    public void setStudentMapper(StudentMapper studentMapper) {
        this.studentMapper = studentMapper;
    }

    @Autowired
    public void setAcademyMapper(AcademyMapper academyMapper) {
        this.academyMapper = academyMapper;
    }





    /**
     * 封装学生信息
     * @param studentVO
     * @return
     */
    @Override
    public Student makeStudent(StudentVO studentVO) {

        Grade grade=gradeService.getGradeBygraName(studentVO.getGrade());

        Student student=new Student();
        student.setStuId(studentVO.getStuId().intValue());
        student.setStuName(studentVO.getStuName());
        student.setStuPhone(studentVO.getStuPhone().intValue());
        student.setGraId(grade.getGraId());
        return student;
    }

    @Override
    public Student getStudentById(Integer stu_id) {
        getStudents();
        students.stream()
                .filter(s-> Objects.equals(s.getStuId(), stu_id))
                .forEach(s-> studentAtomicReference.set(s));
        if (studentAtomicReference.get().getStuId()==null){
            return null;
        }
        return studentAtomicReference.get();
    }

    @Override
    public void updateStudentById(Integer stuId, Student student) {
        studentMapper.update(student,
                new QueryWrapper<Student>()
                        .eq("stu_id", stuId));
        updateRedisOfStudents();
    }

    @Override
    public List<Student> getAllStudent() {
        getStudents();
        return students;
    }

    @Override
    public List<Student> getAllStudentByGraName(String graName) {
        Grade grade=gradeService.getGradeBygraName(graName);
        getStudents();
        List<Student> list=new ArrayList<>();
        students.stream()
                .filter(s->s.getGraId().equals(grade.getGraId()))
                .forEach(list::add);
        return list;
    }

    @Override
    public StudentVO getStudentVOById(int parseInt) {
        Student student=getStudentById(parseInt);
        Grade grade=gradeService.getGradeById(student.getGraId());
        Academy academy=academyService.getAcademyById(grade.getAcaId());
        return new StudentVO(student,grade,academy);
    }

    @Override
    public Student getStudentByStuName(String stuName) {
        getStudents();
        students.stream()
                .filter(s->s.getStuName().equals(stuName))
                .forEach(s->studentAtomicReference.set(s));
        return studentAtomicReference.get();
    }

    private void getStudents(){
        students= (List<Student>) redisTemplate.opsForValue().get(RedisKey.ALL_STUDENT);
        if (students==null){
            updateRedisOfStudents();
        }
    }

    private void updateRedisOfStudents(){
        students=list();
        redisTemplate.opsForValue().set(RedisKey.ALL_STUDENT,students,7, TimeUnit.DAYS);
    }
}
